package service

import (
	"context"
	"errors"
	"fmt"
	v1 "server_go/api/v1"
	"server_go/internal/model"
	"server_go/internal/repository"

	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
	"time"
)

type UsersService interface {
	UsersLogin(ctx context.Context, req v1.UsersLoginRequest) (model.Users, string, error)
	UsersRegister(ctx context.Context, req v1.UsersRegisterRequest) (model.Users, error)
	ChangePassword(ctx context.Context, req v1.UsersChangePasswordRequest) error
}

func NewUsersService(
	service *Service,
	usersRepository repository.UsersRepository,
) UsersService {
	return &usersService{
		Service:         service,
		usersRepository: usersRepository,
	}
}

type usersService struct {
	*Service
	usersRepository repository.UsersRepository
}

func (s *usersService) UsersLogin(ctx context.Context, req v1.UsersLoginRequest) (model.Users, string, error) {
	if req.Account == "" || req.Password == "" {
		return model.Users{}, "", v1.ErrBadRequest
	}

	users, err := s.usersRepository.GetUsersByAccount(ctx, req.Account)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return model.Users{}, "", v1.ErrAdminNotFound
		}
		return model.Users{}, "", v1.ErrInternalServerError
	}

	if users.Type != model.UsersType {
		return model.Users{}, "", v1.ErrType
	}

	err = bcrypt.CompareHashAndPassword([]byte(users.Password), []byte(req.Password))
	if err != nil {
		return model.Users{}, "", v1.ErrPwd
	}

	token, _ := s.jwt.GenToken(users.ID, time.Now().Add(time.Hour*24*7), model.UsersType, 0)
	return *users, token, nil
}

// 用户注册
func (s *usersService) UsersRegister(ctx context.Context, req v1.UsersRegisterRequest) (model.Users, error) {

	if req.Account == "" || req.Password == "" || req.Name == "" {
		return model.Users{}, v1.ErrBadRequest
	}

	// 检查账号是否已存在
	_, err := s.usersRepository.GetUsersByAccount(ctx, req.Account)
	if err == nil {
		return model.Users{}, v1.ErrAdminAccountAlreadyUse
	}

	hashPwd, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
	if err != nil {
		return model.Users{}, v1.ErrInternalServerError
	}

	user := model.Users{
		Account:  req.Account,
		Password: string(hashPwd),
		Name:     req.Name,
		Type:     2, // 普通用户
	}

	err = s.usersRepository.CreateUsers(ctx, &user)
	if err != nil {
		return model.Users{}, v1.ErrInternalServerError
	}
	return user, nil
}

// // 用户修改密码
func (s *usersService) ChangePassword(ctx context.Context, req v1.UsersChangePasswordRequest) error {
	// 查询用户
	user, err := s.usersRepository.GetUserByID(ctx, req.UserID)
	if err != nil {
		return v1.ErrAdminNotFound
	}

	fmt.Print("password: ", user.Password)
	// 校验原密码
	err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.OldPassword))
	if err != nil {
		return v1.ErrPwd // 原密码不匹配
	}

	// 加密新密码
	hashedPwd, err := bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost)
	if err != nil {
		return v1.ErrInternalServerError
	}

	err = s.usersRepository.UpdatePassword(ctx, req.UserID, string(hashedPwd))
	if err != nil {
		return nil
	}

	return nil
}
